package cn.chenli.job.tool.engine.common;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 所需工具
 *
 * @author chenli
 * @create 2017-08-11
 */
public class ToolEngine {

    /**
     * 编译后的正则表达式缓存
     */
    private static final Map<String, Pattern> PATTERN_CACHE = new ConcurrentHashMap<>();

    /**
     * 写文件
     * @param str：写入内容
     * @param fileName：文件名称
     * @param encode：字符集
     */
    public static void writeString2File(String str, String fileName, String encode) throws Exception {
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try (Writer out = new OutputStreamWriter(new FileOutputStream(fileName), encode)) {
            out.write(str);
            out.flush();
        }
    }

    /**
     * 从字符串中正则检索出类名
     * --单独类名
     * @param code：需要检索的字符串
     */
    public static String getClassName(String code) {
        String name = matcherFirst("class\\s+([\\w\\d$_]+)s*", code);
        if (name == null) return null;
        return name.substring(5, name.length()).trim();
    }

    /**
     * 从字符串中正则检索包名
     * -- 不包含类名
     * @param code：需要检索的字符串
     */
    public static String getPackage(String code) {
        String name = matcherFirst("package\\s+([\\w\\d$.]+)s*", code);
        if (name == null) return null;
        return name.substring(7, name.length()).trim();
    }

    public static String matcherFirst(String patternStr, String text) {
        Pattern pattern = compileRegex(patternStr);
        Matcher matcher = pattern.matcher(text);
        String group = null;
        if (matcher.find()) {
            group = matcher.group();
        }
        return group;
    }

    /**
     * 编译一个正则表达式，并且进行缓存,如果换成已存在则使用缓存
     *
     * @param regex 表达式
     * @return 编译后的Pattern
     */
    public static Pattern compileRegex(String regex) {
        Pattern pattern = PATTERN_CACHE.get(regex);
        if (pattern == null) {
            pattern = Pattern.compile(regex);
            PATTERN_CACHE.put(regex, pattern);
        }
        return pattern;
    }

    public static boolean instanceOf(Class clazz, Class target) {
        if (clazz == null) return false;
        if (clazz == target) return true;
        if (target.isInterface()) {
            for (Class aClass : clazz.getInterfaces()) {
                if (aClass == target) return true;
            }
        }
        if (clazz.getSuperclass() == target) return true;
        else {
            if (clazz.isInterface()) {
                for (Class aClass : clazz.getInterfaces()) {
                    if (instanceOf(aClass, target)) return true;
                }
            }
            return instanceOf(clazz.getSuperclass(), target);
        }
    }

    /**
     * 把字符串进行MD5加密
     *
     * @param string 字符串
     * @return MD5加密后的字符串
     */
    public static String defaultEncode(String string) {
        StringBuilder sb = new StringBuilder(32);
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashValue = md.digest(string.getBytes());
            for (int i = 0; i < hashValue.length; i++) {
                sb.append(Integer.toHexString((hashValue[i] & 0xf0) >> 4));
                sb.append(Integer.toHexString(hashValue[i] & 0x0f));
            }
        } catch (NoSuchAlgorithmException e) {
        }
        return sb.toString();
    }
}